package luj.tool.jnproxyan.proxy.network.socks.actor.root.message.admin.connect.history;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import luj.tool.jnproxyan.proxy.admin.http.render.TimeValueRenderer;
import luj.tool.jnproxyan.proxy.admin.http.render.ValueDefaultRenderer;
import luj.tool.jnproxyan.proxy.database.DatabaseState;
import luj.tool.jnproxyan.proxy.network.socks.actor.root.Socks5Actor;
import luj.tool.jnproxyan.proxy.stats.history.ConnectHistoryDat;
import luj.tool.jnproxyan.proxy.stats.history.HistoryItem;
import luj.tool.jnproxyan.proxy.util.data.wrap.ResultGlobalLWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.Comparator.comparing;

@Component
final class OnConnectHistory implements Socks5Actor.Handler<ConnectHistoryMsg> {

  @Override
  public void onHandle(Context ctx) throws Exception {
    Socks5Actor self = ctx.getActorState(this);
    ConnectHistoryMsg msg = ctx.getMessage(this);

    DatabaseState dbState = self.getDatabaseState();
    var historyDat = _dataLoader.load(dbState).andWrap(ConnectHistoryDat.class);

    List<?> itemList = historyDat.history().values().stream()
        .sorted(comparing((HistoryItem i) -> i.connectStartTime().get()).reversed())
        .map(this::makeRow)
        .collect(Collectors.toList());

    Map<String, ?> table = ImmutableMap.of(
        "header", ImmutableList.of("时间", "地址", "结果", "代理"),
        "body", itemList
    );

    msg.http().responsePage(ImmutableMap.of(
        "table", table
    ));
  }

  private Map<String, ?> makeRow(HistoryItem item) {
    return ImmutableMap.of(
        "data", renderItem(item),
        "req", item.requestId().toString()
    );
  }

  private List<String> renderItem(HistoryItem item) {
    String startTime = new TimeValueRenderer().render(item.connectStartTime().get());
    String addr = item.targetHost() + ":" + item.targetPort();

    //TODO: 转成中文
    String result = item.connectResult().get();

    return Stream.of(startTime, addr, result, "否")
        .map(s -> new ValueDefaultRenderer(s).render())
        .collect(Collectors.toList());
  }

  @Autowired
  ResultGlobalLWrapper _dataLoader;
}
